<?php

abstract class Action {
	public function __construct(){
		$this->mode = $this->GetDefaultMode();
	}
	public static function Make($class) { return new $class(); }
	public static function MakeGeneric($classname){
		$c = new ReflectionClass($classname);
		return $c->getMethod('Make')->invoke(null,$classname);
	}

	public final function GetName() { return substr(get_class($this),6); }
	public function IsActive(){ return false; }









	public function GetWidth(){ return 500; }
	public function GetHeight(){ return 375; }

	public function GetIconName() { return 'oxy/ico/Icon'; }
	public function GetIconSrc($size=16){ return $this->GetIconName().$size.'.gif'; }
	public function GetIcon($size=16) { return '<img src="'.$this->GetIconSrc($size).'" width="'.$size.'" height="'.$size.'" alt="" />'; }
	public final function GetIconScr16(){ return $this->GetIconSrc(16); }
	public final function GetIconScr32(){ return $this->GetIconSrc(32); }
	public final function GetIconScr48(){ return $this->GetIconSrc(48); }
	public final function GetIcon16() { return $this->GetIcon(16); }
	public final function GetIcon32() { return $this->GetIcon(32); }
	public final function GetIcon48() { return $this->GetIcon(48); }

	public final function GetLink(){ return '<a'.($this->IsActive()?' class="active"':'').' href="'.new Html($this->GetHref()).'">'.$this->GetIcon16().new Spacer(2).$this->GetTitle().'</a>'; }
	public final function GetLinkedTitle(){ return '<a'.($this->IsActive()?' class="active"':'').' href="'.new Html($this->GetHref()).'">'.$this->GetTitle().'</a>'; }
	public final function GetLinkedIcon($size=16){ return '<a'.($this->IsActive()?' class="active"':'').' href="'.new Html($this->GetHref()).'">'.$this->GetIcon($size).'</a>'; }


	public function GetContentType(){ return Oxygen::GetContentType(); }
	public function GetCharset(){ return Oxygen::GetCharset(); }
	public function GetTitle(){ return Lemma::Retrieve(get_class($this)); }
	public function GetPathTitle(){ return $this->GetTitle(); }
	public function GetParentAction(){ return null; }
	public function GetPath(){ $r = array(); for ($act = $this; !is_null($act); $act = $act->GetParentAction()) $r[] = $act; return array_reverse($r); }
	public function GetMenu() { return new Menu(); }

	public function GetButton() { return '<input type="button" class="formButton" value="'.$this->GetTitle().'" onclick="document.location.href='.new Js($this->GetHref()).'\'" />'; }

	public abstract function IsPermitted();
	public function RequiresLogin(){ return true; }
	public function IsTitleHidden(){ return false; }

	public abstract function Render();
	public function OnBeforeRender() {}
	public function OnAfterRender() {}

	public function GetHead(){
		return '<meta http-equiv="Content-Type" content="text/html" charset="UTF-8" />'
					.'<script type="text/javascript" src="oxy/jsc/prototype.js"></script>'
					.'<script type="text/javascript" src="oxy/jsc/scriptaculous.js?load=effects"></script>'
					.'<link href="oxy/css/oxygen.css" rel="stylesheet" type="text/css" />';
	}

	public final function GetContent(){
		$result = '';
		ob_start();
		try {
			if (!$this->IsPermitted()) throw new SecurityException();
			$this->OnBeforeRender();
			$this->Render();
			$this->OnAfterRender();
		}
		catch (ApplicationException $ex){
			ob_clean();
			if (Log::IsImmediateFlushingEnabled()) {
				Log::WriteException($ex);
			}
			elseif ($this->IsAjax() && $this->IsDialog()){
				echo new MessageControl($ex);
				echo '<br/>' . ButtonControl::Make()->WithValue(Lemma::Retrieve('Close'))->WithOnClick('HideAjaxDialog();');
			}
			else {
				echo '<table class="center"><tr><td>';
				echo '<table cellspacing="20" cellpadding="0" border="0"><tr><td>';
				echo '<table cellspacing="0" cellpadding="15" border="0"><tr>';
				echo '<td align="right"><img src="oxy/ico/Warning32.gif" /><br/>'.new Spacer(50).'</td>';
				echo '<td>'.new Spacer(1,150).'</td>';
				echo '<td style="border-left:1px solid #dddddd;text-align:left;">'.new Spacer(350);
				echo '<br/><br/><br/><b>'.new MessageControl($ex).'</b>';
				echo '<br/><br/><br/>' . ButtonControl::Make()->WithValue(Lemma::Retrieve('Back'))->WithOnClick('history.back();');
				echo '</td>';
				echo '</tr></table>';
				echo '</td></tr></table>';
				echo '</td></tr></table>';
			}
		}
		catch (SecurityException $ex){
			ob_clean();
			if (Log::IsImmediateFlushingEnabled()) {
				Log::WriteException($ex);
			}
			else {
				echo '<table class="center"><tr><td>';
				echo '<table cellspacing="20" cellpadding="0" border="0"><tr><td>';
				echo '<table cellspacing="0" cellpadding="15" border="0"><tr>';
				echo '<td align="right"><img src="oxy/ico/Warning32.gif" /><br/>'.new Spacer(50).'</td>';
				echo '<td>'.new Spacer(1,150).'</td>';
				echo '<td style="border-left:1px solid #dddddd;text-align:left;">'.new Spacer(350).'<br/>'.LoginControl::Make()->WithMessage($ex->getMessage())->WithRedirectOnSuccess($this).'</td>';
				echo '</tr></table>';
				echo '</td></tr></table>';
				echo '</td></tr></table>';
			}
		}
		catch (Exception $ex){
			ob_clean();
			if (Log::IsImmediateFlushingEnabled()) {
				Log::WriteException($ex);
			}
			else {
				echo '<table class="center"><tr><td>';
				echo '<table cellspacing="20" cellpadding="0" border="0"><tr><td>';
				echo '<table cellspacing="0" cellpadding="15" border="0"><tr>';
				echo '<td align="right" valign="top">'.new Spacer(50,30).'<br/>'.new Icon('oxy/ico/Error',32).'</td>';
				echo '<td>'.new Spacer(1,150).'</td>';
				echo '<td style="border-left:1px solid #dddddd;text-align:left;">'.new Spacer(350);
				echo '<br/><br/><b>'.$ex->getMessage().'</b><br/><br/><i>'.basename($ex->getFile()).'['.$ex->getLine().']</i>';
				echo '<div style="font:11px/13px Trebuchet MS,sans-serif;margin-top:20px;white-space:pre;color:#999999;">'.$ex->getTraceAsString().'</div>';
				echo '<div style="font:11px/13px Trebuchet MS,sans-serif;margin-top:20px;white-space:pre;color:#999999;">'.Database::GetQueriesAsString().'</div>';
				echo '</td>';
				echo '</tr></table>';
				echo '</td></tr></table>';
				echo '</td></tr></table>';
			}
		}
		$result = ob_get_clean();
		return $result;
	}

	public function __toString() { return $this->GetHref();	}











	//
	//
	// Href creation
	//
	//
	const NORMAL      = 0x00;
	const AJAX        = 0x01;
	const DIALOG      = 0x02;
	const AJAX_DIALOG = 0x03;
	protected $mode = self::NORMAL;
	public final function IsAjax(){ return ($this->mode & self::AJAX) == self::AJAX; }
	public final function IsDialog(){ return ($this->mode & self::DIALOG) == self::DIALOG; }
	public final function IsAjaxDialog(){ return ($this->mode & self::AJAX_DIALOG) == self::AJAX_DIALOG; }
	protected function GetDefaultMode(){ return self::NORMAL; }
	public final function WithMode($value){ $this->mode = $value; return $this; }
	protected function UseJavascriptAsHref(){ return $this->IsDialog(); }
	public final function GetHref($args=array()){
		return $this->UseJavascriptAsHref() ? $this->GetHrefJavascript($args) : $this->GetHrefPlain($args);
	}
	public final function GetHrefJavascript($args=array()){
		return 'javascript:'.$this->GetJSCommand($args);
	}
	public function GetJSCommand($args=array()){
		if ($this->IsAjaxDialog())
			return 'ShowAjaxDialog('.new Js($this->GetIcon(32)).','.new Js($this->GetTitle()).','.new Js($this->GetHrefPlain($args)).','.new Js($this->GetWidth()).','.new Js($this->GetHeight()).');';
		else
			return 'window.location.href='.new Js($this->GetHrefPlain($args)).';';
	}
	protected function GetUrlArgs(){ return array(); }
	private function GetDefaultUrlArgs(){
		$r = $this->GetUrlArgs();
		$r['action'] = $this->GetName();
		if ($this->mode != self::NORMAL) $r['mode'] = $this->mode;
		return $r;
	}
	public final function GetHrefPlain($args=array()){
		$a = $this->GetDefaultUrlArgs();
		foreach ($args as $key=>$value)
			$a[$key] = $value;
		return Oxygen::MakeHrefFromUrlArgs($a);
	}
	public function GetForm($name=null){
		if ($this->IsAjax() && $this->IsDialog())
			return '<form'.(is_null($name)?'':' id="'.$name.'"').' method="post" action="" onsubmit="SubmitAjaxDialog(this);return false;" onreset="HideAjaxDialog();"><div class="inline">'.new HiddenControl('AjaxDialogSubmition',true);
		else
			//return '<form'.(is_null($name)?'':' id="'.$name.'"').' method="post" action="'.new Html($this->GetHrefPlain()).'" enctype="multipart/form-data"><div class="inline">';
			return '<form'.(is_null($name)?'':' id="'.$name.'"').' method="post" action="" enctype="multipart/form-data"><div class="inline">';
	}
	public function EndForm(){ return '</div></form>'; }
	protected function IsPostback() {
		if ($this->IsAjaxDialog())
			return Oxygen::IsPostback() && Http::$POST['AjaxDialogSubmition']->AsBoolean();
		else
			return Oxygen::IsPostback();
	}

}
?>
